/*
**
**			Heroes IV
**	  Copyright 2001, The 3DO Company
**
**      dialog_kingdom_trade.cpp
*/
// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "dialog_kingdom_trade.h"

#include "adaptor_handler.h"
#include "adventure_frame.h"
#include "adventure_map.h"
#include "army.h"
#include "basic_dialog.h"
#include "bitmap_group.h"
#include "bitmap_group_ptr.h"
#include "bitmap_group_cache.h"
#include "bitmap_layer.h"
#include "bitmap_layer_window.h"
#include "bound_handler.h"
#include "button.h"
#include "button_cache.h"
#include "elements_of.h"
#include "external_string.h"
#include "format_string.h"
#include "game_replace_keywords.h"
#include "interface_help.h"
#include "player.h"
#include "player_color.h"
#include "rational.h"
#include "replace_keywords.h"
#include "scrollbar.h"
#include "standard_fonts.h"


extern  t_button_cache const		k_buy_button;
extern  t_button_cache const		k_close_button;
extern t_bitmap_group_cache const   k_large_material_bitmaps;
extern t_bitmap_group_cache			g_banners_55;
extern t_button_cache				g_max_button;

t_bitmap_group_cache k_kingdom_trade_bitmaps( "dialog.kindom_trade" );

static t_external_string const k_text_kingdom_trade_allies( "allies.kingdom_trade" );

static t_button* create_kingdom_trade_material_button ( t_screen_point &point, t_window *parent_window, 
														int material_type,
														std::string keyword, t_help_block const& help_block )
{
	t_button*				button;
	t_window*				window;
	t_screen_point          origin(0,0);
	t_bitmap_layer const*   layer;
	t_bitmap_group_ptr      material_bitmaps_ptr = k_large_material_bitmaps.get();
    
	button = new t_button( point, parent_window );
    layer = material_bitmaps_ptr->find ( k_material_keyword[ material_type ] );
    window = new t_bitmap_layer_window( layer, origin, button );
	set_help( window, help_block, keyword );

	button->set_released_image( window );
	button->set_pressed_image( window );

	button->update_size();

	return button;
}

static t_button* create_kingdom_trade_player_button (	t_screen_point &point, 
														t_window *parent_window, 
														t_player_color player_color,
														t_help_block const& help_block )
{
	t_button*				button;
	t_window*				window;
	t_screen_point          origin(0,0);
	t_bitmap_layer const*   layer;
	t_bitmap_group_ptr      flag_bitmaps_ptr = g_banners_55.get();
    
	button = new t_button( point, parent_window );
    layer = flag_bitmaps_ptr->find ( k_player_color_keyword[player_color] );
    window = new t_bitmap_layer_window( layer, origin, button );
	set_help( window, help_block, k_player_color_keyword[player_color] );

	button->set_released_image( window );
	button->set_pressed_image( window );

	button->update_size();

	return button;
}

t_dialog_kingdom_trade::t_dialog_kingdom_trade ( t_window *parent)
					: t_window( k_completely_transparent, parent )
{
    m_material_index = -1;
    m_target_player_index = -1;
    m_quantity = 0;
}

void t_dialog_kingdom_trade::init_dialog( t_window* parent, t_adventure_frame* frame, std::string const& name_text, std::string const& intro_text )
{

	t_bitmap_layer const*   layer;
	//t_window *              window;
	t_window *              background_window;
	t_screen_point          origin(0,0);
	t_screen_point          point(0,0);
	t_screen_rect           rect;
	t_bitmap_group_ptr      material_bitmaps_ptr = k_large_material_bitmaps.get();
    int                     i;
	t_help_block const&     material_help = get_help_block( "material_display" );
	t_help_block const&		help = get_help_block( "kingdom_trade" );

	m_frame = frame;

	m_player_ptr = &frame->get_map()->get_player();
	m_player_funds = m_player_ptr->get_funds()[k_gold];
	m_bitmaps_ptr = k_kingdom_trade_bitmaps.get();

	layer = m_bitmaps_ptr->find( "background" );
	background_window = new t_bitmap_layer_window( layer, origin, this );

	// Get the flag frame
	layer = m_bitmaps_ptr->find( "flag_highlight" );
   	rect = layer->get_rect();
	m_flag_frame = new t_bitmap_layer_window( layer, -rect.top_left(), this ); 
	m_flag_frame->update_size();

    // Find 1st player frame (first item) - get diff for frame.
	t_screen_point  player_frame_diff(0,0);

    point = m_bitmaps_ptr->find( "flag_1" )->get_rect().top_left();
    player_frame_diff = (point - rect.top_left());

	// Get the material frame
	layer = m_bitmaps_ptr->find( "frame" );
   	rect = layer->get_rect();
	m_material_frame = new t_bitmap_layer_window( layer, -rect.top_left(), this ); 
	m_material_frame->update_size();

    // Find frame for first itme (gold) - get diff for frame.
	t_screen_point  frame_diff(0,0);

    point = m_bitmaps_ptr->find( "gold_icon" )->get_rect().top_left();
    frame_diff = (point - rect.top_left());

    /*
    ** Materials:
    */
	std::string     material_icon_text;

	for (i=0; i<k_material_count; i++)
    {
        // Player's material.
		material_icon_text = format_string ( "%s_icon", k_material_keyword[i] );
	    rect = m_bitmaps_ptr->find( material_icon_text )->get_rect();
        m_material_button[i] = create_kingdom_trade_material_button ( rect.top_left(), background_window, i,
                        k_material_keyword[i], help );
	
        m_material_button[i]->set_click_handler( add_2nd_argument( bound_handler( *this, &t_dialog_kingdom_trade::material_clicked ), i ) );
	    m_frame_locations.push_back ( rect.top_left() - frame_diff );
    }

	// set the give icon
	layer = m_bitmaps_ptr->find( "give_icon" );
	rect = layer->get_rect();
	m_give_icon = new t_bitmap_layer_window( layer, rect.top_left(), this ); 

    /*
    ** Player flags
    */
	t_bitmap_group_ptr      flag_bitmaps_ptr = g_banners_55.get();
	int flag_index = 0;

	// Setup data for each potential trading partner
	for (i=0; i<m_frame->get_map()->get_player_count(); i++)
    {
		t_player * player_ptr = m_frame->get_map()->get_players()[i].get();

		// Only allow trade with other players you are allied with
		if( is_ally( m_player_ptr, player_ptr ) )
		{
			rect = m_bitmaps_ptr->find( format_string ( "flag_%d", flag_index + 1 ) )->get_rect();

			m_player_button[flag_index] = create_kingdom_trade_player_button ( rect.top_left(), background_window, 
																	player_ptr->get_color(), help );

			m_player_color[flag_index] = player_ptr->get_color();
		
			m_player_button[flag_index]->set_click_handler( add_2nd_argument( bound_handler( *this, &t_dialog_kingdom_trade::flag_clicked ), flag_index ) );
			m_player_frame_locations.push_back ( rect.top_left() - player_frame_diff );
			flag_index++;
		}
    }

	// NULL out the data for the rest of the slots
	assert( flag_index <= ELEMENTS_OF(m_player_color) );
	assert( ELEMENTS_OF(m_player_color) == ELEMENTS_OF(m_player_button) );
	for (i=flag_index; i<ELEMENTS_OF(m_player_color); i++)
	{
		m_player_color[i]	= k_player_none;
		m_player_button[i]	= NULL;
	}

    /*
    ** Create buttons.
    */
	t_button            *button_ptr;
	t_button_handler    button_handler;

	rect = m_bitmaps_ptr->find( "close_button" )->get_rect();
	button_ptr = new t_button( k_close_button.get(), rect.top_left(), this );
	button_ptr->set_click_handler( bound_handler( *this, &t_dialog_kingdom_trade::close_click ));

    /*
    ** Add give button.
    */
	point = m_bitmaps_ptr->find( "give_released" )->get_rect().top_left() + origin;
	m_give_button = create_button( m_bitmaps_ptr, "give", this );
	button_handler = bound_handler( *this, &t_dialog_kingdom_trade::give_clicked );
	m_give_button->set_click_handler( button_handler );
	set_help( m_give_button, help, "give" );

    // Add max button.
	point = m_bitmaps_ptr->find( "max_button" )->get_rect().top_left() + origin;
	m_max_button = new t_button( g_max_button.get(), point, this );
	button_handler = bound_handler( *this, &t_dialog_kingdom_trade::max_clicked );
	m_max_button->set_click_handler( button_handler );
	set_help( m_max_button, help, "maximum" );

    /*
    ** Add scrollbar.
    */
	layer = m_bitmaps_ptr->find( "scrollbar" );
	rect  = layer->get_rect();

	m_scrollbar = new t_scrollbar( rect.top_left(), rect.width(), this, 0, 0, false );
	m_scrollbar->set_handler( bound_handler( *this, &t_dialog_kingdom_trade::scrollbar_move ) );
	m_scrollbar->set_position( 0 );
	m_scrollbar->set_limits( 0, 0 );

    /*
    ** Text windows.
    */
	t_text_window* text_window_ptr;

    // Title.
	rect = m_bitmaps_ptr->find( "title" )->get_rect() + origin;
	text_window_ptr = new t_text_window( get_font( 20 ), rect, this, name_text, t_pixel_24(0,0,0));
	text_window_ptr->set_center_horizontal();
	text_window_ptr->set_drop_shadow( false );

    // Intro text.
	rect = m_bitmaps_ptr->find( "text" )->get_rect() + origin;
	text_window_ptr = new t_text_window( get_font( 20 ), rect, this, intro_text, t_pixel_24(0,0,0));
	text_window_ptr->set_center_horizontal();
	text_window_ptr->set_drop_shadow( false );

	// Allies text	
	rect = m_bitmaps_ptr->find( "allies" )->get_rect() + origin;
	text_window_ptr = new t_text_window( get_font( rect.height() ), rect, this, k_text_kingdom_trade_allies, t_pixel_24(0,0,0));
	text_window_ptr->set_center_horizontal();
	text_window_ptr->set_drop_shadow( false );

	std::string     material_text_box;
	t_material_array const& funds = m_player_ptr->get_funds();
    
	for (i=0; i<k_material_count; i++)
    {
        // Player's material amount.
		material_text_box = format_string ( "%s_text", k_material_keyword[i] );
	    rect = m_bitmaps_ptr->find( material_text_box )->get_rect();
	    m_amount_text[i] = new t_text_window( get_font( 16 ), rect, this, "", t_pixel_24(0,0,0));
	    m_amount_text[i]->set_center_horizontal();
    }

    // Player quantity text.
	rect = m_bitmaps_ptr->find( "give_text" )->get_rect() + origin;
	m_quantity_text = new t_text_window( get_font( rect.height() ), rect, this, "", t_pixel_24(0,0,0));
	m_quantity_text->set_center_horizontal();
	m_quantity_text->set_drop_shadow( false );

	// Set the selected to the first player and material
	flag_clicked( NULL, 0 );
	material_clicked( NULL, 0 );
  	m_quantity_text->set_text ( "0" );

    show_material_amount();

    /*
    ** Center the position and display the window.
    */
    t_screen_rect parent_rect = get_parent()->get_client_rect();
    
    rect = m_bitmaps_ptr->get_rect();
    rect += (parent_rect.size() - rect.size()) / 2;
    init( rect );

}

void t_dialog_kingdom_trade::show_material_amount()
{
	t_material_array const& funds = m_player_ptr->get_funds();
    int                     i;
	t_bitmap_layer const*   layer;
	t_bitmap_group_ptr      material_bitmaps_ptr = k_large_material_bitmaps.get();

	for (i=0; i<k_material_count; i++)
    {
        // Player's side.  Kindgom amount.
		m_amount_text[i]->set_text( format_string( "%d", funds[i] ) );
    }

    m_max_quantity = funds[m_material_index];
    m_scrollbar->set_limits( 0, m_max_quantity );
  	m_quantity_text->set_text ( format_string( "%d", m_quantity ) );

	// set the give icon bitmap
    layer = material_bitmaps_ptr->find ( k_material_keyword[ m_material_index ] );
	m_give_icon->set_bitmap( layer, true );
}

// Moved scroll bar.
void t_dialog_kingdom_trade::scrollbar_move( t_scrollbar* scrollbar, int value )
{
    m_quantity = value;
  	m_quantity_text->set_text ( format_string( "%d", m_quantity ) );
}

void t_dialog_kingdom_trade::flag_clicked( t_button* button, int index )
{
    if (m_target_player_index == index)
        return;

	// Set the target player
	t_player * player_ptr = m_frame->get_map()->get_player(m_player_color[index]);

	if( !player_ptr )
		return;

    m_target_player_index = index;
	m_target_player_ptr = player_ptr;

    // Set frame.
   	m_flag_frame->move( m_player_frame_locations[index] );
}

void t_dialog_kingdom_trade::give_clicked( t_button* button )
{
	if ( m_quantity == 0 )
        return;

    // Purchase exchange.
	m_player_ptr->spend( (t_material)m_material_index, m_quantity );
	m_target_player_ptr->gain( (t_material)m_material_index, m_quantity );

    show_material_amount();
}

void t_dialog_kingdom_trade::material_clicked( t_button* button, int index )
{
    if (m_material_index == index)
        return;

    m_material_index = index;

    // Set frame.
   	m_material_frame->move( m_frame_locations[index] );

	m_scrollbar->set_position( 0 );

    // Reset quantity.
    m_quantity = 0;

    show_material_amount();
}

void t_dialog_kingdom_trade::max_clicked( t_button* button )
{
	m_scrollbar->set_position( m_max_quantity );
}

void t_dialog_kingdom_trade::close_click( t_button* button )
{

	m_return_value = false;
	close();
}

